#include <windows.h>
#include <process.h>
#include <iostream>
#include <string>

int seed;

__global__ void kernel(int *p, int s)
{
  int blkid = gridDim.x * blockIdx.y + blockIdx.x;
  int thid = blockDim.x * threadIdx.y + threadIdx.x;

  int id = thid;

  p[id] = id + s;
}


DWORD ThreadProc(LPVOID lpdwThreadParam)
{
  bool & loop = *(bool *)lpdwThreadParam;
  
  int *p = NULL;
  int m[10] = {0, };
  cudaMalloc((void**)&p, sizeof(int) * 100);
  dim3 dimBlock(2, 5);
  
  while(loop) {

    if(seed == 0)
      Sleep(100);

    else {

      kernel<<<1, dimBlock>>>(p, seed);
      cudaMemcpy(m, p, sizeof(int)*10, cudaMemcpyDeviceToHost);      
      for(int i = 0; i < 10; ++i)
        printf("%d\n", m[i]);

      seed = 0;
    }

  }

  std::cout << "thread successfully terminated" << std::endl;
  return 0;
}

void mainProcedure(HANDLE &handle, bool &loop);

int main(int argc, char ** argv)
{
  DWORD dwThreadId;
  HANDLE hThread;
  bool loop = true;

  hThread = CreateThread(
    NULL, // default security
    0,    // default stack size
    (LPTHREAD_START_ROUTINE)&ThreadProc, // routine to execute
    (LPVOID)&loop, // thread parameter
    0,    // immediately run the thread
    &dwThreadId);

  if(hThread == NULL) {
    fputs("error creating thread.", stderr);
    return EXIT_FAILURE;
  }

  mainProcedure(hThread, loop); 

  return EXIT_SUCCESS;
}


void mainProcedure(HANDLE &handle, bool &loop)
{
  std::string line;

  while(true) {

    std::getline(std::cin, line);

    if(line == "q") {
      loop = false;
      break;
    }      
    else {

      std::cout << line << std::endl;
      seed = atoi(line.c_str());

    }

  }

  DWORD dwObject = WaitForSingleObject(handle, 3000);
  if(dwObject == WAIT_FAILED) {
    std::cerr << "wait failed: " << __LINE__ << std::endl;
    return;
  } else {
    ;
  }

}